#include "Protocol.hpp"
#include "Socket.hpp"
#include <iostream>
#include <string>
#include <unistd.h>

#include <ctime>
#include <cstdlib>

using namespace std;
using namespace Protocol;
using namespace Network;

int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        cout << "Usage:\n     ./udp_echo_server <ip> <port>" << endl;
        return 0;
    }

    string serverip = argv[1];
    uint16_t serverport = stoi(argv[2]);

    Network::Socket *coon = new Network::TcpSocket();
    if (!coon->BuildconnectSocketMethod(serverip, serverport))
    {
        cerr << "connect failed" << serverip << ":" << serverport << endl;
        return 0;
    }
    cout << "connect success" << serverip << ":" << serverport << endl;


    unique_ptr<Factory> factory = make_unique<Factory>(); //????

    srand((unsigned int)time(nullptr) ^ getpid());
    const string opers = "+-*/%^=&";
    while (true)
    {
        // 构建一个请求
        int x = rand() % 100;
        usleep(77777);
        int y = rand() % 100;

        char oper = opers[rand() % opers.size()];
        shared_ptr<Request> req = factory->BuildRequest(x, y, oper);

        // 2.对请求进行序列化
        string requeststr;
        req->Serialize(&requeststr);

        string testreq=requeststr;
        testreq+=" =";

        // 3.添加报头
        requeststr = Encode(requeststr);

        // 4发送请求
        coon->Send(requeststr);

        while (true)
        {
            // 5.读取响应
            string responsestr;
            if(!coon->Recv(&responsestr, 1024))break;

            // 6.解析响应
            string response;
            if (!Decode(responsestr, &response))
            {
                continue;
            }

            //7.response "result code"
            auto resp=factory->BuildReponse();
            resp->Deserialize(response);
            
            //8.得到计算结果
            cout<<testreq<<resp->GetResult()<<"["<<resp->GetCode()<<"]"<<endl;
            break;
        }
        sleep(1);

    }

    coon->CloseSocket();
    sleep(10);
    return 0;
}
